package com.waigoulin.domain.auth.service;

import com.google.common.cache.Cache;
import com.waigoulin.domain.auth.adapter.port.ILoginPort;
import com.waigoulin.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @FileName WeixinLoginService
 * @Description 登录服务领域层接口实现类
 * @Author waigoulin
 * @date 2025-07-30
 **/
@Slf4j
@Service
public class WeixinLoginService implements ILoginService {

    @Resource
    private ILoginPort loginPort; // 基础设施层的登录接口实现类

    // Guava 库的 Cache 实现缓存（本地缓存）
    @Resource
    private Cache<String, String> openidToken; // <ticket, openid>

    // Redis实现缓存（分布式缓存）
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Value("${weixin.config.ticket.expire-seconds}")
    private int openid_expire_time; // 用户openid过期时间

    @Override
    public String createQrCodeTicket() throws Exception {
        return loginPort.createQrCodeTicket();
    }

    @Override
    public String checkLogin(String ticket) {
        // 从 Cache 缓存中获取 openid
        // return openidToken.getIfPresent(ticket);

        // 从 Redis 缓存中获取 openid
        return redisTemplate.opsForValue().get(buildOpenidKey(ticket));
    }

    private String buildOpenidKey(String ticket) {
        return Constants.REDIS_WEIXIN_PREFIX + Constants.RedisKeyEnum.OPENID_TOKEN.getKeyPrefix() + ticket;
    }

    @Override
    public void saveLoginState(String ticket, String openid) throws IOException {
        // 扫码登陆进行验签时会调用该方法保存登录状态

        // 1. 将登录凭证和用户id绑定，即<ticket, openid>，缓存到 Cache 中
        // Guava 库的 Cache 缓存 <ticket, openid>
        openidToken.put(ticket, openid);
        //  Redis 缓存 <ticket, openid>
        redisTemplate.opsForValue().set(buildOpenidKey(ticket), openid, openid_expire_time, TimeUnit.SECONDS);

        // 2. 发送模板消息
        loginPort.sendLoginTemplateMessage(openid);
    }
}


